package com.kuwou.workobject.Utils;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 音乐信息爬取工具类
 */
public final class MusicCrawlerUtils {
    // 常量定义
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0";
    private static final String ACCEPT_HEADER = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7";
    private static final String ACCEPT_LANGUAGE = "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6";
    private static final int TIMEOUT = 5000;
    private static final int PAGE_LOAD_WAIT = 200;

    // 在工具类初始化时添加日志屏蔽
    static {
        // 屏蔽Selenium的CDP警告日志
        Logger.getLogger("org.openqa.selenium").setLevel(Level.SEVERE);
        Logger.getLogger("org.openqa.selenium.devtools").setLevel(Level.SEVERE);
        Logger.getLogger("org.openqa.selenium.chromium").setLevel(Level.SEVERE);
    }

    // 私有构造方法，防止实例化
    private MusicCrawlerUtils() {
        throw new AssertionError("工具类不允许实例化");
    }

    /**
     * 爬取指定搜索关键词的音乐信息
     * @param searchUrl 搜索页面URL
     * @param chromeDriverPath ChromeDriver路径
     * @throws IOException 网络请求异常
     */
    public static Map<String, Object> crawlMusicInfo(String searchUrl, String chromeDriverPath) throws IOException {
        HashMap<String, Object> result = new HashMap<>();
        // 初始化文档
        Document document = getDocument(searchUrl);
        Elements playList = document.getElementsByClass("play_list");

        if (playList == null || playList.isEmpty()) {
            System.out.println("未找到播放列表");
            result.put("result", false);
            result.put("msg", "未找到播放列表");
            return result;
        }

        // 配置ChromeDriver
        System.setProperty("webdriver.chrome.driver", chromeDriverPath);
        ChromeOptions options = createChromeOptions();

        // 处理播放列表
        return processPlayList(playList, options);
    }

    /**
     * 创建Chrome浏览器配置
     * @return ChromeOptions配置对象
     */
    private static ChromeOptions createChromeOptions() {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless"); // 无头模式
        options.addArguments("--disable-gpu");
        options.addArguments("--user-agent=" + USER_AGENT);
        return options;
    }

    /**
     * 获取网页文档
     * @param url 网页URL
     * @return Jsoup文档对象
     * @throws IOException 网络请求异常
     */
    private static Document getDocument(String url) throws IOException {
        return Jsoup.connect(url)
                .userAgent(USER_AGENT)
                .header("Accept", ACCEPT_HEADER)
                .header("Accept-Language", ACCEPT_LANGUAGE)
                .timeout(TIMEOUT)
                .get();
    }

    /**
     * 处理播放列表
     * @param playList 播放列表元素
     * @param options Chrome浏览器配置
     */
    private static Map<String, Object> processPlayList(Elements playList, ChromeOptions options) {
        Map<String, Object> result = new HashMap<>();
        String message =  "";

        result.put("result", false);

        Element ul = playList.select("ul").first();
        if (ul == null) {
            message = "播放列表未找到UL元素";
            System.out.println("播放列表中未找到UL元素");
            result.put("msg", message);
            return result;
        }

        Elements lis = ul.getElementsByTag("li");
        if (lis.isEmpty()) {
            message = "播放列表为空";
            System.out.println("播放列表为空");
            result.put("msg", message);
            return result;
        }

        // 循环处理每个音乐条目（替代递归）
        for (int i = 0; i < lis.size(); i++) {
            result = processMusicItem(lis.get(i), options);
            if ((Boolean) result.get("result")) break;
        }
        return result;
    }

    /**
     * 处理单个音乐条目
     * @param li 音乐条目元素
     * @param options Chrome浏览器配置
     */
    private static Map<String, Object> processMusicItem(Element li, ChromeOptions options) {
        Map<String, Object> result = new HashMap<>();
        String message =  "";
        result.put("result", false);

        Element link = li.getElementsByTag("a").first();
        if (link == null) {
            message = "音乐条目未找到链接";
            System.out.println(message);
            result.put("msg", message);
            return result;
        }

        String href = link.attr("href");
        href = "https://www.2t58.com" + href;
//        String name = link.text();
//        System.out.println("爬取到：" + name + "：" + href);

        WebDriver driver = null;
        try {
            driver = new ChromeDriver(options);
            driver.get(href);
            Thread.sleep(PAGE_LOAD_WAIT);

            String pageSource = driver.getPageSource();
            Document doc = Jsoup.parse(pageSource);

            // 提取音频信息
            result = extractAudioInfo(doc);

        } catch (InterruptedException e) {
            System.err.println("处理音乐时发生中断：" + e.getMessage());
            Thread.currentThread().interrupt(); // 恢复中断状态
        } finally {
            if (driver != null) {
                driver.quit(); // 确保浏览器关闭
            }
        }

        return result;
    }

    /**
     * 提取音频信息
     * @param doc 网页文档对象
     */
    private static Map<String, Object> extractAudioInfo(Document doc) {
        Map<String, Object> result = new HashMap<>();
        Boolean flag = false;
        String message = "";
        result.put("result", flag);
        result.put("msg", message);

        Element audioElement = doc.getElementById("jp_audio_0");
        Element nameElement = doc.getElementsByClass("djname").first();

        if (nameElement == null) {
            message = "未找到歌手信息元素";
            System.out.println(message);
            result.put("msg", message);
            return result;
        }

        Elements h1s = nameElement.getElementsByTag("h1");
        if (h1s.isEmpty()) {
            message = "未找到歌手名称元素";
            System.out.println(message);
            result.put("msg", message);
            return result;
        }

        String singerName = h1s.get(0).ownText();

        if (audioElement != null) {
            String audioSrc = audioElement.attr("src");
            message = singerName + "：" + audioSrc;
//            System.out.println("音频地址src：" + message);
            flag = true;
            result.put("result", flag);
            result.put("msg", message);
        }
        return result;
    }

    // 使用示例
    public static void main(String[] args) throws IOException {
        String searchUrl = "https://www.2t58.com/so/晴天.html";
        String chromeDriverPath = "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe";
        Map<String, Object> stringObjectMap = MusicCrawlerUtils.crawlMusicInfo(searchUrl, chromeDriverPath);
        System.out.println(stringObjectMap.toString());
    }
}
